﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DomainDriver.CommonUtilities.Enums;
using DomainDriver.CommonUtilities.Reflectors;
using DomainDriver.DomainModeling.Attributes;
using DomainDriver.DomainModeling.Constraints;
using DomainDriver.DomainModeling.DomainModels;
using DomainDriver.DomainModeling.DomainObjects;
using DomainDriver.DomainModeling.Repositories;

namespace DomainDriver.DomainModeling.Example.DomainObjects
{
    public enum EnumerationValue
    {
        Option1,
        Option2,
        Option3,
        Option4
    }

    public partial class EnumerationDomainObject : EnumDomainObject<EnumerationValue, EnumerationDomainObject>
    {
        public static new void LoadEnumerationsValues(IDomainModel domainModel)
        {
            IRepository<EnumerationValue, EnumerationDomainObject> repository = domainModel.GetRepository<EnumerationValue, EnumerationDomainObject>();
            Type enumType = typeof(EnumerationValue);
            IndexConstraint<EnumerationValue, EnumerationDomainObject> indexConstraint = null;
            bool hasIndex = domainModel.HasConstraint<IndexConstraint<EnumerationValue, EnumerationDomainObject>>();
            if (hasIndex)
            {
                indexConstraint = domainModel.GetConstraint<IndexConstraint<EnumerationValue, EnumerationDomainObject>>();
            }

            foreach (EnumerationValue key in Enum.GetValues(enumType))
            {
                if (repository.Exists(key))
                { continue; }

                EnumerationDomainObject domainObject = new EnumerationDomainObject();
                int indexValue = 0;

                if (hasIndex)
                { indexValue = indexConstraint.GetIndexValueForObject(domainObject); }

                domainObject.m_Key = key;
                domainObject.m_Index = indexValue;
                repository.Add(domainObject);
            }
        }

        private int m_Index;

        public EnumerationDomainObject()
            : this(0)
        { }

        public EnumerationDomainObject(int enumValueAsInt)
            : this(EnumUtilities.ConvertIntToEnum<EnumerationValue>(enumValueAsInt), enumValueAsInt + IndexConstraint<EnumerationValue, EnumerationDomainObject>.IndexStartValue)
        { }

        public EnumerationDomainObject(EnumerationValue enumValue)
            : this(enumValue, (int)enumValue + 1)
        { }

        public EnumerationDomainObject(int enumValueAsInt, int indexValue)
            : this(EnumUtilities.ConvertIntToEnum<EnumerationValue>(enumValueAsInt), indexValue)
        { }

        public EnumerationDomainObject(EnumerationValue enumValue, int indexValue)
            : base(enumValue)
        {
            m_Index = indexValue;
        }

        public int Index
        {
            get { return m_Index; }
        }

        public override void CopyTo(EnumerationDomainObject receivingObject)
        {
            base.CopyTo(receivingObject);
            receivingObject.m_Index = m_Index;
        }

        public override bool Equals(EnumerationDomainObject otherObject)
        {
            if (!m_Index.Equals(otherObject.m_Index))
            { return false; }
            return base.Equals(otherObject);
        }
    }
}